
#include "Team.h"
#include "Utils/Vector2D.h"
#include "Utils/Util.h"
#include "World.h"
#include "Map.h"

#include <vector>
#include <string>
#include <cassert>
#include <iostream>

Team::Team(unsigned id, std::string name) :
    team_id(id), team_name(name), team_flag(NULL) {

    team_score = 0;

    switch(team_id){
      case 0:
        team_col_r = 255;
        team_col_g = 0;
        team_col_b = 0;
        break;
      case 1:
        team_col_r = 0;
        team_col_g = 0;
        team_col_b = 255;
        break;
      case 2:
        team_col_r = 0;
        team_col_g = 255;
        team_col_b = 0;
        break;
      default:
        std::cerr << team_id << std::endl;
        assert(false);
    }
}

Team::~Team(){
}


void Team::addPlayer(Player *player){
    team_players.push_back(player);
}

std::vector<Player*> Team::getPlayers(void){
    return team_players;
}

void Team::setFlag(Flag *flag){
    team_flag = flag;

    // once we know the home position of our team's flag 
    // we can generate the spawn points.
    generateSpawnPoints();
}

Flag* Team::getFlag(void){
    return team_flag;
}

unsigned Team::getTeamId(void){
    return team_id;
}


std::string Team::getTeamName(void){
    return team_name;
}


void Team::getTeamColour(unsigned char &r, unsigned char &g, unsigned char &b){
    r = team_col_r;
    g = team_col_g;
    b = team_col_b;
}


Vector2D Team::getRandomSpawnPoint(void){
    assert(spawn_points.size() > 0);
    unsigned index = rand()%spawn_points.size();
    return spawn_points[index];
}


int Team::getTeamScore(void){
    return team_score;
}


void Team::changeTeamScore(int score_delta){
    team_score += score_delta;
}


float Team::minSpawnPointDist(Vector2D pos){
    float min_dist = 0.0f;
    for(unsigned i = 0; i < spawn_points.size(); i++){
        if(i == 0 || (spawn_points[i] - pos).length() < min_dist){
            min_dist = (spawn_points[i] - pos).length();
        }
    }
    return min_dist;
}


void Team::generateSpawnPoints(void){
    float max_flag_dist = World::instance().getMap()->getWidth();
    max_flag_dist /= 8.0f;

    for(unsigned i = 0; i < 5; i++){
        Vector2D pos_offset(Util::rand_interval(-max_flag_dist, max_flag_dist), 
                            Util::rand_interval(-max_flag_dist, max_flag_dist));

        while(World::instance().getMap()->pointInsideObstacle(team_flag->getHomePosition()+pos_offset, true) ||
              !World::instance().getMap()->pointInsideMap(team_flag->getHomePosition()+pos_offset)){
            pos_offset = Vector2D(Util::rand_interval(-max_flag_dist, max_flag_dist), 
                                  Util::rand_interval(-max_flag_dist, max_flag_dist));
        }

        spawn_points.push_back(team_flag->getHomePosition() + pos_offset);
    }
}

